package login

import (
	"context"
	"errors"
	"github.com/google/uuid"
	"github.com/kuangshp/go-utils/k"
	"github.com/spf13/cast"
	"insighttracking/common/enum"
	"insighttracking/common/utils"
	"insighttracking/query/dao"
	"insighttracking/query/service"
	"net/http"
	"time"

	"insighttracking/apps/sorting/internal/svc"
	"insighttracking/apps/sorting/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"os"
)

type LoginApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewLoginApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *LoginApiLogic {
	hostname, _ := os.Hostname()
	return &LoginApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *LoginApiLogic) LoginApi(req *types.LoginReq) (resp *types.LoginResp, err error) {
	accountEntity, err := dao.AccountEntity.WithContext(l.ctx).Where(
		dao.AccountEntity.Username.Eq(req.Username),
		dao.AccountEntity.AccountType.Eq(enum.EnterprisePersonEnum),
	).First()
	if err != nil {
		l.Logger.Errorf("登录失败-根据用户名获取数据失败", err)
		return nil, errors.New("无该账号信息，登录失败")
	}
	if accountEntity.Status == 2 {
		return nil, errors.New("该用户已禁用，请联系管理员处理")
	}
	if utils.Md5(req.Password, accountEntity.Salt) != accountEntity.Password {
		l.Logger.Error("登录失败-账号密码错误")
		return nil, errors.New("登录失败")
	}
	// 查询员工信息
	personEntity, err := dao.EnterprisePersonEntity.WithContext(l.ctx).Where(
		dao.EnterprisePersonEntity.EnterpriseID.Eq(accountEntity.EnterpriseID),
		dao.EnterprisePersonEntity.ID.Eq(accountEntity.PersonID),
	).First()
	var mobile = ""
	var email = ""
	var roleName = ""
	var roleId int64
	var personId int64
	var personName = ""
	if err == nil {
		mobile = personEntity.Mobile
		email = personEntity.Email
		roleId = personEntity.RoleID
		personId = personEntity.ID
		personName = personEntity.Name
		roleEntity, err := service.RoleService.GetByIdApi(l.ctx, personEntity.RoleID)
		if err == nil {
			roleName = roleEntity.Name
		}
	}

	clientIP := utils.ClientIP(l.Request)
	resp = &types.LoginResp{
		AccountID:     accountEntity.AccountID,                                                            // 主键id
		Username:      accountEntity.Username,                                                             // 用户名
		Status:        accountEntity.Status,                                                               // 状态0表示正常,1表示禁用
		AccountType:   accountEntity.AccountType,                                                          // 账号类型,0表示超管,1表示后台运营人员,2表示企业账号,3表示门店账号
		Mobile:        mobile,                                                                             // 联系方式
		Email:         email,                                                                              // 电邮地址
		EnterpriseID:  accountEntity.EnterpriseID,                                                         // 企业id
		CustomerID:    accountEntity.CustomerID,                                                           // 员工账号
		LastLoginDate: k.If(accountEntity.LastLoginDate.IsZero(), 0, utils.TimestampToString(time.Now())), // 最后登录时间
		LastLoginIP:   clientIP,                                                                           // 最后登录ip地址
		CreatedAt:     utils.TimestampToString(accountEntity.CreatedAt),                                   // 创建时间
		UpdatedAt:     utils.TimestampToString(accountEntity.UpdatedAt),                                   // 更新时间
		RoleId:        roleId,                                                                             // 角色id
		RoleName:      roleName,                                                                           // 角色名称
		PersonId:      cast.ToInt64(personId),
		PersonName:    personName,
	}
	token, err := utils.GenerateToken(l.svcCtx.RedisDb, accountEntity.AccountID, k.MapToString(resp), "purchase")
	if err != nil {
		l.Logger.Errorf("登录失败-存储redis失败", err.Error())
		return nil, errors.New("登录失败")
	}
	// 修改最后一次登录信息
	_, _ = dao.AccountEntity.WithContext(l.ctx).Where(dao.AccountEntity.AccountID.Eq(accountEntity.AccountID)).UpdateSimple(
		dao.AccountEntity.LastLoginDate.Value(time.Now()),
		dao.AccountEntity.LastLoginIP.Value(clientIP),
	)
	resp.Token = token
	return
}
